<!--
 * Copyright © 2022 XXXXXXXXX
 * @Author: zhangxiang
 * @Date: 2022-08-26 14:36:32
 * @LastEditors: zhangxiang
 * @LastEditTime: 2023-09-26 15:05:57
 * @Description:
 *
-->

<template>
  <div class="scale-strategy-ctn">
    <div class="services">
      <!-- 微服务选择器 -->
      <el-checkbox-group v-model="checkList" class="checkbox">
        <el-checkbox
          v-for="item in microServices"
          :key="item.svcId"
          :label="item.svcId"
          :disabled="
            hasAddScaleStrategy(item.scaleStrategy) ||
              cannotSettingScale(item.scheduleStrategy)
          "
        >{{ item.svcName }}
          <div v-if="isGPU(item.scheduleStrategy)" class="arch">
            GPU
          </div></el-checkbox>
      </el-checkbox-group>
      <div class="hint">
        <i class="el-icon-info icon"></i>
        <div class="text">
          支持多选微服务，批量添加策略，也可以单选微服务逐个添加策略。添加策略之后不可以重复添加，已添加策略的微服务置灰
        </div>
      </div>
    </div>
    <div class="add-btn" @click="addClick">
      <i class="el-icon-circle-plus icon"></i>
      <div class="text">添加弹性扩缩策略</div>
    </div>
    <div class="strategies-v2">
      <div v-for="(item, index) in addedStrategy" :key="index" class="strategy">
        <div class="top">
          <span class="name">{{ item.serviceName }}</span>
          <img
            class="img edit"
            src="@/assets/imgs/intelligent-scheduling/icon_edit.png"
            alt=""
            @click="editClick(item)"
          />
          <el-popover
            :ref="`popover-delete-${index}`"
            placement="top"
            width="300"
          >
            <p>是否确认删除该策略？</p>
            <div style="text-align: right; margin: 0">
              <el-button
                size="mini"
                type="text"
                @click="$refs[`popover-delete-${index}`][0].doClose()"
              >取消</el-button>
              <el-button
                type="primary"
                size="mini"
                @click="deleteClick(item, index)"
              >确定</el-button>
            </div>
            <img
              slot="reference"
              class="img"
              src="@/assets/imgs/intelligent-scheduling/icon_delete.png"
              alt=""
            />
          </el-popover>
        </div>
        <div class="center">
          <div
            v-for="(sitem, sindex) in item.scaleStrategy"
            :key="sindex"
            class="column"
          >
            <div class="name">{{ getScaleTypeName(sitem.scaleType) }}</div>
            <div
              v-if="sitem.strategyParam.includes(policyNoneStr)"
              class="configure not"
            >
              不配置
            </div>
            <div v-else class="configure">配置</div>
          </div>
        </div>
      </div>
    </div>
    <!-- 步骤按钮 -->
    <el-row type="flex" justify="end" style="margin-top: 30px">
      <el-button
        class="common-btn"
        size="medium"
        @click="$emit('previous-step')"
      >上一步</el-button>
      <el-button
        class="common-btn"
        type="primary"
        size="medium"
        :disabled="!enableNextStep"
        @click="$emit('next-step')"
      >下一步</el-button>
    </el-row>
    <!-- 添加/编辑 弹窗 -->
    <ScaleStrategyDialogV2
      v-if="showDialog"
      :show.sync="showDialog"
      :is-edit="isEditDialog"
      :info="currentStrategyInfo"
      :choosed-clusters="userChooseClusters"
      @edit-success="editSuccessCallback"
      @add-success="addSuccessCallback"
    />
  </div>
</template>

<script>
import {
  STRATEGY_SCALE_TYPE,
  getClusterProviderChn,
  GPU_BUSINESS_SCENE,
  UNSCALE_BUSINESS_SCENES
} from '@/utils/cnap/constant'
import ScaleStrategyDialogV2 from '../../components/ScaleStrategyDialogV2.vue'
import { deleteScaleStrategy } from '@/api/cnap/app-service'

export default {
  name: 'ScaleStrategy',
  components: { ScaleStrategyDialogV2 },
  props: {
    // 微服务
    microServices: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      checkList: [], // 已选择的微服务
      policyNoneStr: 'policy":"none',
      userChooseClusters: [],
      showDialog: false, // 弹窗显示
      isEditDialog: false, // 是否编辑
      currentStrategyInfo: {} // 当前策略信息
    }
  },
  computed: {
    /**
     * @description: 下一步按钮可点击
     * @return {*}
     */
    enableNextStep() {
      let enable = true
      this.microServices.forEach(element => {
        if (!this.cannotSettingScale(element.scheduleStrategy)) {
          enable = enable && this.hasAddScaleStrategy(element.scaleStrategy)
        }
      })
      return enable
    },
    /**
     * @description: 已添加的策略
     * @return {*}
     */
    addedStrategy() {
      const arr = []
      for (const item of this.microServices) {
        // 循环
        if (
          Array.isArray(item.scaleStrategy) &&
          item.scaleStrategy.length > 0
        ) {
          // 三种扩缩容策略都配置了
          // 规定顺序排序
          item.scaleStrategy.sort((x, y) => {
            return (
              Object.keys(STRATEGY_SCALE_TYPE).indexOf(x.scaleType) -
              Object.keys(STRATEGY_SCALE_TYPE).indexOf(y.scaleType)
            )
          })
          arr.push({
            serviceId: item.svcId, // serviceId
            serviceName: item.svcName, // 服务名
            serviceStatus: item.status, // 微服务状态
            category: item.category, // 类别
            scaleStrategy: item.scaleStrategy // 策略
          })
        }
      }
      return arr
    }
  },
  methods: {
    /**
     * @description: 不可以配置扩缩容
     * @param {*} scheduleStrategy
     * @return {*}
     */
    cannotSettingScale(scheduleStrategy) {
      if (
        scheduleStrategy &&
        scheduleStrategy.businessScene &&
        scheduleStrategy.businessScene.svcType
      ) {
        return UNSCALE_BUSINESS_SCENES.includes(
          scheduleStrategy.businessScene.svcType
        )
      }
      return false
    },
    /**
     * @description: 是GPU
     * @param {*} scheduleStrategy
     * @return {*}
     */
    isGPU(scheduleStrategy) {
      return (
        scheduleStrategy &&
        scheduleStrategy.businessScene &&
        scheduleStrategy.businessScene.svcType === GPU_BUSINESS_SCENE
      )
    },
    /**
     * @description: 扩缩容策略类别名称
     * @param {*} name
     * @return {*}
     */
    getScaleTypeName(name) {
      if (Object.keys(STRATEGY_SCALE_TYPE).includes(name)) {
        return STRATEGY_SCALE_TYPE[name].label
      }
      return ''
    },
    /**
     * @description: 添加成功回调
     * @return {*}
     */
    addSuccessCallback() {
      this.checkList = []
      this.$emit('refreshMicroService') // 刷新微服务
    },
    /**
     * @description: 编辑成功回调
     * @return {*}
     */
    editSuccessCallback() {
      this.checkList = []
      this.$emit('refreshMicroService') // 刷新微服务
    },
    /**
     * @description: 新增
     * @return {*}
     */
    addClick() {
      if (this.checkList.length === 0) {
        // 未选择微服务
        this.$message.warning({
          message: '请先选择微服务',
          duration: 1500
        })
        return
      }
      // 获取服务名称
      // 循环查找出服务名
      const serviceNames = []
      this.microServices.forEach((element) => {
        if (this.checkList.includes(element.svcId)) {
          serviceNames.push(element.svcName)
        }
      })
      this.computeUserChooseClusters(this.checkList)
      // 组装策略信息
      this.currentStrategyInfo = {
        serviceIds: this.checkList,
        serviceNames: serviceNames
      }
      this.isEditDialog = false // 创建
      this.showDialog = true // 展示弹窗
    },
    /**
     * @description: 编辑
     * @param {*} item
     * @return {*}
     */
    editClick(item) {
      if (item.serviceStatus !== '0') {
        // 微服务运行中无法编辑
        this.$message.warning({
          message: '微服务运行中，暂时无法编辑策略',
          duration: 1500
        })
        return
      }
      // 编辑
      this.computeUserChooseClusters([item.serviceId])
      this.currentStrategyInfo = item
      this.isEditDialog = true // 编辑
      this.showDialog = true // 展示弹窗
    },
    /**
     * @description: 计算用户准备编辑微服务的云商-集群
     * @param {*} svcIds
     * @return {*}
     */
    computeUserChooseClusters(svcIds) {
      const arr = []
      const svcs = this.microServices.filter((svc) => {
        return svcIds.includes(svc.svcId)
      })
      for (const item of svcs) {
        if (
          item.scheduleStrategy &&
          Array.isArray(item.scheduleStrategy.algDeployClusterInfos)
        ) {
          const findInfo = item.scheduleStrategy.algDeployClusterInfos.find(
            (info) => {
              return (
                info.providerName === item.scheduleStrategy.userChooseCloud &&
                info.name
              )
            }
          )
          if (findInfo) {
            arr.push({
              clusterName: findInfo.name,
              providerName: getClusterProviderChn(
                this.$store.state.app.cloudVendors,
                findInfo.providerName
              )
            })
          }
        }
      }
      this.userChooseClusters = arr
    },
    /**
     * @description: 是否已添加扩缩容策略
     * @param {*} scaleStrategy
     * @return {*}
     */
    hasAddScaleStrategy(scaleStrategy) {
      return Array.isArray(scaleStrategy) && scaleStrategy.length > 0
    },
    /**
     * @description: 删除
     * @param {*} item
     * @param {*} index
     * @return {*}
     */
    deleteClick(item, index) {
      if (item.serviceStatus !== '0') {
        // 微服务运行中无法删除
        this.$message.warning({
          message: '微服务运行中，暂时无法删除策略',
          duration: 1500
        })
        return
      }
      const ids = []
      item.scaleStrategy.forEach((element) => {
        ids.push(element.id)
      })
      // 删除
      deleteScaleStrategy(ids).then((res) => {
        this.$refs[`popover-delete-${index}`][0].doClose() // 取消popover
        this.$message.success({
          message: '删除成功',
          duration: 2000
        })
        this.$emit('refreshMicroService') // 刷新微服务
      })
    }
  }
}
</script>

<style lang="less" scoped>
@import "@/assets/css/common.less";
.scale-strategy-ctn {
  .services {
    display: flex;
    align-items: center;

    .checkbox {
      /deep/ .el-checkbox__label {
        color: #4a4a4a;
      }
      .arch {
        margin-left: 5px;
        display: inline-block;
        padding: 0 10px;
        box-sizing: border-box;
        height: 24px;
        line-height: 22px;
        background: rgba(255, 255, 255, 0.8);
        border-radius: 12px;
        border: 1px solid #027dec;
        .textStyle(14px, 500, #027dec);
      }
    }

    .hint {
      margin-left: 30px;
      display: flex;
      align-items: center;
      .icon {
        font-size: 17px;
        color: #c3c3c3;
        margin-right: 5px;
      }
      .text {
        .textStyle(14px , 400, #C3C3C3);
        line-height: 20px;
      }
    }
  }

  .add-btn {
    margin-top: 25px;
    box-sizing: border-box;
    height: 40px;
    background: #d9ebff;
    border-radius: 4px;
    border: 1px dashed #0091ff;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    .icon {
      color: #0091ff;
      font-size: 20px;
    }
    .text {
      .textStyle(14px, 500, #0091ff);
      line-height: 20px;
      margin-left: 5px;
    }
  }

  .strategies-v2 {
    margin-top: 25px;
    display: grid;
    grid-template-columns: 1fr 1fr 1fr 1fr;
    grid-template-rows: auto;
    grid-column-gap: 20px;
    grid-row-gap: 20px;

    .strategy {
      min-width: 280px;
      box-sizing: border-box;
      background: linear-gradient(213deg, #00c4ff 0%, #0091ff 100%);
      border-radius: 6px;
      padding: 10px 20px 20px;
      display: flex;
      flex-direction: column;

      .top {
        display: flex;
        align-items: center;

        .name {
          .textStyle(16px, 600, #FFFFFF);
          line-height: 22px;
        }

        .img {
          width: 13px;
          cursor: pointer;

          &.edit {
            margin-left: auto;
            margin-right: 10px;
          }
        }

        /deep/ .el-popover__reference-wrapper {
          display: flex;
          align-items: center;
        }
      }

      .center {
        background: #ffffff;
        border-radius: 7px;
        box-sizing: border-box;
        padding: 15px 20px;
        margin-top: 10px;

        .column {
          display: flex;
          align-items: center;

          .name {
            min-width: 85px;
            margin-right: 20px;
            text-align: right;
            .textStyle(14px , 500, #B9B9B9);
            line-height: 20px;
          }

          .configure {
            .textStyle(14px , 500, #0091ff);
            line-height: 20px;
            &.not {
              color: #4a4a4a;
            }
          }
        }
      }
    }
  }
}
</style>
